package org.g4studio.core.orm.xibatis.sqlmap.client;

import java.sql.Connection;

/**
 * A thread safe client for working with your SQL Maps (Start Here). This
 * interface inherits transaction control and execution methods from the
 * SqlMapTransactionManager and SqlMapExecutor interfaces.
 * <p/>
 * The SqlMapClient is the central class for working with SQL Maps. This class
 * will allow you to run mapped statements (select, insert, update, delete
 * etc.), and also demarcate transactions and work with batches. Once you have
 * an SqlMapClient instance, everything you need to work with SQL Maps is easily
 * available.
 * <p/>
 * The SqlMapClient can either be worked with directly as a multi-threaded
 * client (internal session management), or you can get a single threaded
 * session and work with that. There may be a slight performance increase if you
 * explicitly get a session (using the openSession() method), as it saves the
 * SqlMapClient from having to manage threads contexts. But for most cases it
 * won't make much of a difference, so choose whichever paradigm suits your
 * needs or preferences.
 * <p/>
 * An SqlMapClient instance can be safely made <i>static</i> or applied as a
 * <i>Singleton</i>. Generally it's a good idea to make a simple configuration
 * class that will configure the instance (using SqlMapClientBuilder) and
 * provide access to it.
 * <p/>
 * <b>The following example will demonstrate the use of SqlMapClient.</b>
 * 
 * <pre>
 * <i><font color="green">
 * //
 * // autocommit simple query --these are just examples...not patterns
 * //
 * </font></i>
 * Employee emp = (Employee) <b>sqlMap.queryForObject("getEmployee", new Integer(1))</b>;
 * <i><font color="green">
 * //
 * // transaction --these are just examples...not patterns
 * //
 * </font></i>
 * try {
 *   <b>sqlMap.startTransaction()</b>
 *   Employee emp2 = new Employee();
 *   // ...set emp2 data
 *   Integer generatedKey = (Integer) <b>sqlMap.insert ("insertEmployee", emp2)</b>;
 *   emp2.setFavouriteColour ("green");
 *   <b>sqlMap.update("updateEmployee", emp2)</b>;
 *   <b>sqlMap.commitTransaction()</b>;
 * } finally {
 *   <b>sqlMap.endTransaction()</b>;
 * }
 * <i><font color="green">
 * //
 * // session --these are just examples...not patterns
 * //
 * </font></i>
 * try {
 *   <b>SqlMapSession session = sqlMap.openSession()</b>
 *   <b>session.startTransaction()</b>
 *   Employee emp2 = new Employee();
 *   // ...set emp2 data
 *   Integer generatedKey = (Integer) <b>session.insert ("insertEmployee", emp2)</b>;
 *   emp2.setFavouriteColour ("green");
 *   <b>session.update("updateEmployee", emp2)</b>;
 *   <b>session.commitTransaction()</b>;
 * } finally {
 *   try {
 *     <b>session.endTransaction()</b>;
 *   } finally {
 *     <b>session.close()</b>;
 *   }
 *   // Generally your session scope would be in a wider context and therefore the
 *   // ugly nested finally block above would not be there.  Realize that sessions
 *   // MUST be closed if explicitly opened (via openSession()).
 * }
 * <i><font color="green">
 * //
 * // batch --these are just examples...not patterns
 * //
 * </font></i>
 * try {
 *   <b>sqlMap.startTransaction()</b>
 *   List list = (Employee) <b>sqlMap.queryForList("getFiredEmployees", null)</b>;
 *   <b>sqlMap.startBatch ()</b>;
 *   for (int i=0, n=list.size(); i < n; i++) {
 *     <b>sqlMap.delete ("deleteEmployee", list.get(i))</b>;
 *   }
 *   <b>sqlMap.executeBatch()</b>;
 *   <b>sqlMap.commitTransaction()</b>;
 * } finally {
 *   <b>sqlMap.endTransaction()</b>;
 * }
 * </pre>
 * 
 * @see SqlMapClientBuilder
 * @see SqlMapSession
 * @see SqlMapExecutor
 */
public interface SqlMapClient extends SqlMapExecutor, SqlMapTransactionManager {

	/**
	 * Returns a single threaded SqlMapSession implementation for use by one
	 * user. Remember though, that SqlMapClient itself is a thread safe
	 * SqlMapSession implementation, so you can also just work directly with it.
	 * If you do get a session explicitly using this method <b>be sure to close
	 * it!</b> You can close a session using the sqlMapSession.close() method.
	 * <p/>
	 * 
	 * @return An SqlMapSession instance.
	 */
	public SqlMapSession openSession();

	/**
	 * Returns a single threaded SqlMapSession implementation for use by one
	 * user. Remember though, that SqlMapClient itself is a thread safe
	 * SqlMapSession implementation, so you can also just work directly with it.
	 * If you do get a session explicitly using this method <b>be sure to close
	 * it!</b> You can close a session using the SqlMapSession.close() method.
	 * <p/>
	 * This particular implementation takes a user provided connection as a
	 * parameter. This connection will be used for executing statements, and
	 * therefore overrides any configured datasources. Using this approach
	 * allows the developer to easily use an externally supplied connection for
	 * executing statements.
	 * <p/>
	 * <b>Important:</b> Using a user supplied connection basically sidesteps
	 * the datasource so you are responsible for appropriately handling your
	 * connection lifecycle (i.e. closing). Here's a (very) simple example
	 * (throws SQLException):
	 * 
	 * <pre>
	 * try {
	 * 	Connection connection = dataSource.getConnection();
	 * 	SqlMapSession session = sqlMap.openSession(connection);
	 * 	// do work
	 * 	connection.commit();
	 * } catch (SQLException e) {
	 * 	try {
	 * 		if (connection != null)
	 * 			commit.rollback();
	 * 	} catch (SQLException ignored) {
	 * 		// generally ignored
	 * 	}
	 * 	throw e; // rethrow the exception
	 * } finally {
	 * 	try {
	 * 		if (connection != null)
	 * 			connection.close();
	 * 	} catch (SQLException ignored) {
	 * 		// generally ignored
	 * 	}
	 * }
	 * </pre>
	 * 
	 * @param conn
	 *            - the connection to use for the session
	 * 
	 * @return An SqlMapSession instance.
	 */
	public SqlMapSession openSession(Connection conn);

	/**
	 * TODO : Deprecated and will be removed.
	 * 
	 * @return A session (DEPRECATED)
	 * @deprecated Use openSession() instead. THIS METHOD WILL BE REMOVED BEFORE
	 *             FINAL RELEASE.
	 */
	public SqlMapSession getSession();

	/**
	 * Flushes all data caches.
	 */
	public void flushDataCache();

	/**
	 * Flushes the data cache that matches the cache model ID provided. cacheId
	 * should include the namespace, even when useStatementNamespaces="false".
	 * 
	 * @param cacheId
	 *            The cache model to flush
	 */
	public void flushDataCache(String cacheId);

	/**
	 * Returns a generated implementation of a cusom mapper class as specified
	 * by the method parameter. The generated implementation will run mapped
	 * statements by matching the method name to the statement name. The mapped
	 * statement elements determine how the statement is run as per the
	 * following:
	 * <ul>
	 * <li>&lt;insert&gt; -- insert()
	 * <li>&lt;update&gt; -- update()
	 * <li>&lt;delete&gt; -- delete()
	 * <li>&lt;select&gt; -- queryForObject, queryForList or queryForMap, as
	 * determined by signature (see below)
	 * <li>&lt;procedure&gt; -- determined by method name (see below)
	 * </ul>
	 * 
	 * How select statements are run is determined by the method signature, as
	 * per the following:
	 * <ul>
	 * <li>Object methodName (Object param) -- queryForObject
	 * <li>List methodName (Object param [, int skip, int max | , int pageSize])
	 * -- queryForList
	 * <li>Map methodName (Object param, String keyProp [,valueProp]) --
	 * queryForMap
	 * </ul>
	 * 
	 * How stored procedures are run is determined by the method name, as per
	 * the following:
	 * <ul>
	 * <li>insertXxxxx -- insert()
	 * <li>createXxxxx -- insert()
	 * <li>updateXxxxx -- update()
	 * <li>saveXxxxx -- update()
	 * <li>deleteXxxxx -- delete()
	 * <li>removeXxxxx -- delete()
	 * <li>selectXxxxx -- queryForXxxxxx() determined by method signature as
	 * above
	 * <li>queryXxxxx -- queryForXxxxxx() determined by method signature as
	 * above
	 * <li>fetchXxxxx -- queryForXxxxxx() determined by method signature as
	 * above
	 * <li>getXxxxx -- queryForXxxxxx() determined by method signature as above
	 * </ul>
	 * 
	 * @param iface
	 *            The interface that contains methods representing the mapped
	 *            statements contained.
	 * @return An instance of iface that can be used to call mapped statements
	 *         directly in a typesafe manner.
	 */
	// public Object getMapper(Class iface);
}